Java基础知识(四)

Author Avatar
子语 2017 - 10 - 03
  • 在其它设备中阅读本文章

数组的定义及使用

基本概念

1.数组是一组变量的集合。数组属于引用数据类型。
2.数组的定义语法
(1)声明并开辟数组: 数组类型 数组名[] = new 数据类型[数组长度]
(2)分步完成:

// 声明数组
数组类型 数组名[] = null;
// 开辟数组
数组名 = new 数据类型 [数组长度]

3.数组开辟空间用,可利用数组名[下标|索引]访问,下标从0开始。即长度为3的数组,下标值为0,1,2。下标超出范围,会出现数组越界异常(ArrayIndexOutOfBoundsException)。
4.数组是顺序结构且长度固定,可使用循环语句输出,可用数组名.length获取数组长度。

public class Demo {
    public static void main(String[] args) {
        int datas[] = new int[3]; // 声明并开辟一个长度为3的数组
        datas[0] = 1; // 为数组赋值,如不赋值,默认值为0
        datas[1] = 2;
        datas[2] = 3;
        // for循环输出数组内容,datas.length获取数组长度
        for (int x = 0; x < datas.length; x++) {
            System.out.println(datas[x]);
        }
    }
}

5.数组属于**引用数据类型,**因此要进行内存分配。与保存对象的区别是对象的堆内存保存的是属性,数组的堆内存保存的是数据。
无法加载
范例:分步完成

public class Demo {
    public static void main(String[] args) {
        int datas[] = null; // 声明数组
        datas = new int[3]; // 开辟一个长度为3的数组
        datas[0] = 1;
        datas[1] = 2;
        datas[2] = 3;
        for (int x = 0; x < datas.length; x++) {
            System.out.println(datas[x]);
        }
    }
}

无法加载
6.数组可以进行引用传递。

public class Demo {
    public static void main(String[] args) {
        int datas[] = new int[3];
        datas[0] = 1;
        datas[1] = 2;
        datas[2] = 3;
        int temp[] = datas; // 引用传递
        temp[0] = 99;
        for (int x = 0; x < datas.length; x++) {
            System.out.println(datas[x]); // 99 2 3
        }
    }
}

无法加载
以上都是动态初始化数组,即先开辟数组,再为数组赋值。
7.静态初始化数组:
在定义数组的同时为其赋值,语法:
(1)数组类型 数组名[] = {v1, v2 ,…,vn};
(2)数组类型 数组名[] = new 数据类型[] {v1, v2 ,…,vn};
范例:静态初始化数组

public class Demo {
    public static void main(String[] args) {
        int datas[] = new int[]{1, 2, 3}; // 静态初始化数组
        for (int x = 0; x < datas.length; x++) {
            System.out.println(datas[x]);
        }
    }
}

数组支持顺序数据访问,最大缺点是长度不能改变,因此在开发中不直接使用数组,但会使用数组的概念。

二维数组

1.一维数组就是一行数据:

索引 0 1 2 3
数据 0 10 20 30

在一维数组中要查询一个数据,只要确定其索引即可。
二维数组,是一个数据表:

索引 0 1 2 3
0 0 10 20 30
1 1 2 3 4
2 12 123 231 233

二维数组中要查询一个数据,需要定位列和行。二维数组中第一个[]确定行,第二个[]确定列。
2. 二维数组定义语法:

// 动态初始化:
数据类型 数组名称[][]=new 数据类型[行数][列数];
// 静态初始化:
数据类型 数组名称[][]=new 数据类型[][]{数组元素} ;

由此可以发现,二维数组就是将多个一维数组变为一个数组。

public class Demo {
    public static void main(String[] args) {
        int datas[][] = new int[][]{
        	{1, 2, 3}, 
        	{4, 5, 6}, 
        	{7, 8, 9}
        }; 
        // 外层循环控制数组的行
        for (int x = 0; x < datas.length; x++) {
            // 内层循环控制数组的列
            for (int y = 0; y < datas[x].length ; y++) {
                System.out.print(datas[x][y] + "\t");
            }
            System.out.println();
        }
    }
}

数组与方法的引用

1.方法的参数可以是数组:

public class Demo {
    public static void main(String[] args) {
        int datas[] = new int[]{1, 2, 3};
        change(datas);
        for (int x = 0; x < datas.length; x++) {
            System.out.println(datas[x]);
        }
    }

    public static void change(int temp[]) {
        for (int x = 0; x < temp.length; x++) {
            temp[x] *= 2; // 数组元素乘2保存
        }
    }
}

内存分析:
无法加载
change()执行完毕后,temp不再指向datas的堆内存,但change()datas数据的修改被保存下来。
2.数组排序(冒泡排序)
数据的不同会造成排序次数的不同,但不论有多少数据,**总的排序次数不会超过数组长度。**只要排序次数达到数组长度的平方,就能排序成功。

public class ArrayDemo {
    public static void main(String[] args) {
        int datas[] = new int[]{2, 1, 9, 0, 5, 7, 6, 8};
        for (int x = 0; x < datas.length; x++) {
            for (int y = 0; y < datas.length - 1; y++) {
                if (datas[y] > datas[x]) {
                    int t = datas[y];
                    datas[y] = datas[x];
                    datas[x] = t;
                }
            }
            // 为更好地理解冒泡排序,输出每轮排序的结果
            System.out.print("第" + (x + 1) + "次排序结果:");
            print(datas);
            System.out.println();
        }
        print(datas);
    }
    // 数组输出的方法
    public static void print(int temp[]) {
        for (int x = 0; x < temp.length; x++) {
            System.out.print(temp[x] + " ");
        }
    }
}

建议main()是程序的起点,可以称为客户端。客户端的代码逻辑应简单,因此可将排序封装为方法。

public class ArrayDemo {
    public static void main(String[] args) {
        int datas[] = new int[]{2, 1, 9, 0, 5, 7, 6, 8};
        sort(datas);
        print(datas);
    }

    // 数组冒泡排序方法
    public static void sort(int temp[]) {
        for (int x = 0; x < temp.length; x++) {
            for (int y = 0; y < temp.length - 1; y++) {
                if (temp[y] > temp[x]) {
                    int t = temp[y];
                    temp[y] = temp[x];
                    temp[x] = t;
                }
            }
        }
    }

    // 数组输出的方法
    public static void print(int temp[]) {
        for (int x = 0; x < temp.length; x++) {
            System.out.print(temp[x] + " ");
        }
    }
}

3.数组转置
转置的概念(一维数组):·

原始数组 1,2,3,4,5,6,7,8
转置后 8,7,6,5,4,3,2,1

转置操作的两个思路:
(1)定义一个新的数组,而后将原始数组按照倒序的方式插入到新的数组之中,随后改变原始数组的引用:

 public class ArrayDemo {
    public static void main(String[] args) {
        int datas[] = new int[]{1,2,3,4,5,6,7,8};
        datas = reverseOne(datas); // 让datas指向新数组,原始数据成为垃圾
    }
    // 数组逆序输出方法一
    public static int [] reverseOne(int temp[]) {
        // 定义新数组,长度与原始数组一致
        int temps[] = new int[temp.length];
        int foot = temp.length - 1; // 控制原始数组的索引
        for (int x = 0; x < temps.length ; x++) {
            temps[x] = temp[foot]; // 新数组按照原始数组倒序排列
            foot --;
        }
        return temps;
    }
}

上述代码实现转置,但产生了垃圾,不合理。
(2)利用算法,直接在数组上完成转置:
不论数组个数是奇数还是偶数,转换次数 = 数组长度 / 2;

// 数组逆序输出方法
public static void reverse(int temp[]) {
    int len = temp.length / 2;
    int head = 0;
    int tail = temp.length - 1;
    for (int x = 0; x < len; x++) {
        int t = temp[head];
        temp[head] = temp[tail];
        temp[tail] = t;
        head++;
        tail--;
    }
}

4.行列数相等的二维数组转置:

public class Demo {
    public static void main(String[] args) {
        int data[][] = new int[][]{
        	{1, 2, 3}, 
        	{4, 5, 6}, 
        	{7, 8, 9}
        };
        reverse(data);
        print(data);
    }

    // 专门实现数组的倒置操作
    public static void reverse(int arr[][]) {
        for (int x = 0; x < arr.length; x++) {
            for (int y = x; y < arr.length; y++) {
                if (x != y) { //行和列相同,进行交换
                    int temp = arr[x][y];
                    arr[x][y] = arr[y][x];
                    arr[y][x] = temp;
                }
            }
        }
    }

    // 专门输出的方法
    public static void print(int temp[][]) {
        for (int x = 0; x < temp.length; x++) {
            for (int y = 0; y < temp[x].length; y++) {
                System.out.print(temp[x][y] + "、");
            }
            System.out.println();
        }
        System.out.println();
    }

}

转置过程

1[0][0]  2[0][1]  3[0][2]
4[1][0]  5[1][1]  6[1][2]
7[2][0]  8[2][1]  9[2][2]
第一次转换(x=0,y=x=0,循环3次)
 ·y的第一次循环(x==y)
  1[0][0]  2[0][1]  3[0][2]
  4[1][0]  5[1][1]  6[1][2]
  7[2][0]  8[2][1]  9[2][2]
 ·y的第二次循环(x=0,y=1,进行交换)
  1[0][0]  4[1][0]  3[0][2]
  2[0][1]  5[1][1]  6[1][2]
  7[2][0]  8[2][1]  9[2][2]
 ·y的第三次循环(x=0,y=2,进行交换)
  1[0][0]  4[1][0]  7[2][0]
  2[0][1]  5[1][1]  6[1][2]
  3[0][2]  8[2][1]  9[2][2]
第二次转换(x=1,y=x=1,循环2次)
 ·y的第一次循环(x=1,y=1,不交换)
  1[0][0]  4[1][0]  7[2][0]
  2[0][1]  5[1][1]  6[1][2]
  3[0][2]  8[2][1]  9[2][2]
 ·y的第二次循环(x=1,y=2,进行交换)
  1[0][0]  4[1][0]  7[2][0]
  2[0][1]  5[1][1]  8[2][1]
  3[0][2]  6[1][2]  9[2][2]
第三次转换(x=2,y=x=2,循环11次)
 ·y的第二次循环(x=2,y=2,不交换)
  1[0][0]  4[1][0]  7[2][0]
  2[0][1]  5[1][1]  8[2][1]
  3[0][2]  6[1][2]  9[2][2]

行列数不同的数组进行倒置,其思路是:数组的行数是原数组的列数,数组的列数是源数组的行数。需要改变原始数组的引用,会产生垃圾。
5.方法返回数组:

public class Demo {
    public static void main(String[] args) {
        int data[] = init(); // 接收数组
        print(data);
        System.out.println(init().length);
    }

    public static int[] init() {
        return new int[]{1, 2, 3}; // 方法返回数组
    }

    public static void print(int temp[]) {
        for (int x = 0; x < temp.length; x++) {
            System.out.print(temp[x] + "、");
        }
        System.out.println();
    }
}

操作数组的方法

1.Java对数组提供类库支持,下面介绍两个类库中的方法:
(1)数组拷贝:用一个数组的指定内容覆盖另一个数组指定内容。
语法:System.arraycopy(源数组名,源数组拷贝开始索引,目标数组名,目标数组开始拷贝索引,拷贝长度)
范例:数组拷贝
·数组A:1,2,3,4,5,6,7,8;
·数组B:11,22,33,44,55,66,77,88;
·拷贝后的数组B:11,22,5,6,7,66,77,88

 public class Demo {
    public static void main(String[] args) {
        int dataA[] = new int[]{1, 2, 3, 4, 5, 6, 7, 8};
        int dataB[] = new int[]{11, 22, 33, 44, 55, 66, 77, 88};
        System.arraycopy(dataA, 4, dataB, 2, 3);
        ArrayDemo.print(dataB); // 调用之前代码中的数组输出方法
    }
}

(2)数组排序:
语法:java.util.Arrays.sort(数组名)

public class Demo {
    public static void main(String[] args) {
        int dataA[] = new int[]{3, 2, 1, 4, 7, 0, 6, 5};
        java.util.Arrays.sort(dataA);
        ArrayDemo.print(dataA); // 调用之前代码中的数组输出方法
    }
}

对象数组

1.对象数组是将多个对象交由数组处理。
2.对象数组的定义与一般数组一致:
范例: 动态初始化对象数组

class Book {
    private String title;
    private double price;

    public Book(String title, double price) {
        this.title = title;
        this.price = price;
    }

    // setter和getter方法略
    public String getInfo() {
        return "书名:" + title + ",价格:" + price;
    }
}

public class Demo {
    public static void main(String[] args) {
        Book books[] = new Book[3];
        books[0] = new Book("Java开发", 66.6);
        books[1] = new Book("JSP", 6.6);
        books[2] = new Book("C++", 16.6);
        for (int x = 0; x < books.length; x++) {
            System.out.println(books[x].getInfo()); 
//未实例化对象时,输出值全为null
        }
    }  
}

范例:静态初始化对象数组:

class Book {
    private String title;
    private double price;

    public Book(String title, double price) {
        this.title = title;
        this.price = price;
    }

    // setter和getter方法略
    public String getInfo() {
        return "书名:" + title + ",价格:" + price;
    }
}

public class Demo {
    public static void main(String[] args) {
        Book books[] = new Book[]{
                new Book("Java开发", 66.6),
                new Book("JSP", 6.6),
                new Book("C++", 16.6)
        };
        for (int x = 0; x < books.length; x++) {
            //未实例化对象时,输出值全为null
            System.out.println(books[x].getInfo()); 
        }
    }
}

This blog is under a CC BY-NC-SA 3.0 Unported License
本文链接:http://yov.oschina.io/article/Java/Java Base/Java基础知识(四)/